package com.gtm.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gtm.model.Pager;
import com.gtm.model.Topic;
import com.gtm.model.User;
import com.gtm.repository.TopicRepository;
import com.gtm.repository.UserRepository;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.swing.*;
import javax.xml.crypto.Data;
import java.util.*;

/**
 * Created by 骆清波 on 2017/10/28.
 */
@Service
public class TopicService extends BaseService<Topic>{
    @Autowired
    MongoTemplate mt;

    @Autowired
    TopicRepository tpr;

    @Autowired
    UserRepository usr;

    public Topic saveTopic(String tid, String teacherName, String tel, String topicName, String topicSrc, String topicType,
                           String requirement, String introduction, String limitPerson) {
        Topic tpc=new Topic();
        tpc.setTeacherId(tid);
        tpc.setTeacherName(teacherName);
        tpc.setTeacherTel(tel);
        tpc.setTopicName(topicName);
        tpc.setTopicSrc(topicSrc);
        tpc.setTopicType(topicType);
        tpc.setRequirement(requirement);
        tpc.setIntroduction(introduction);
        tpc.setLimitPerson(Integer.parseInt(limitPerson));
        System.out.println(tpc.getLimitPerson());
        return tpr.save(tpc);
    }


    public Page<Topic> listOwnTopic(PageRequest pageRequest, String searchKey, String tid) {
        if (searchKey!=null)
            return tpr.listOwnBySearchKey(searchKey,pageRequest,tid);
        else
            return tpr.listOwnBySearchKey("",pageRequest,tid);
    }

    public Topic updateTopic(String tpid, String topicName, String topicSrc, String topicType, String requirement, String introduction, String limitPerson) {
        Topic tpc=tpr.findOne(tpid);
        tpc.setTopicName(topicName);
        tpc.setTopicSrc(topicSrc);
        tpc.setTopicType(topicType);
        tpc.setRequirement(requirement);
        tpc.setIntroduction(introduction);
        tpc.setLimitPerson(Integer.parseInt(limitPerson));
        return tpr.save(tpc);
    }

    public Pager<Topic> listWithKeyMeta(PageRequest pageRequest, String searchKey) {
        if (searchKey==null) {
            return listToPage(tpr.findAll(), pageRequest);
        }
        JSONObject sk= JSON.parseObject(searchKey);
        Set<String> keys=sk.keySet();
        Criteria inter=new Criteria();
        List<Criteria> listC=new ArrayList<Criteria>();
        for(String s:keys){
            String value=sk.get(s).toString();
            if (value==null)
                continue;
            if (s.equals("markedDel")) {
                listC.add(Criteria.where(s).is(Boolean.valueOf(value)));
            }
            else
                listC.add(Criteria.where(s).regex(value,"i"));
        }
        inter.andOperator(listC.stream().toArray(s->new Criteria[s]));
        List<Topic> tps= mt.find(Query.query(inter),Topic.class);
        if(tps==null)
            return null;
//        PageImpl<Topic> page =new PageImpl<Topic>(tps,pageRequest,tps.size());
        @SuppressWarnings({ "unchecked", "rawtypes" })
        Pager<Topic> pager=listToPage(tps,pageRequest);
        return pager;
    }

    public List<Topic> listWithKey(PageRequest topicType, String searchKey,String isPassed) {
        if (isPassed.equals("all"))
            return tpr.findByTeacherNameLikeOrTeacherTelLikeOrTopicNameLikeOrTopicSrcLikeOrTopicTypeLike(searchKey,searchKey,searchKey,searchKey,searchKey);
        Boolean flag=Boolean.valueOf(isPassed);
        return tpr.findByTeacherNameLikeOrTeacherTelLikeOrTopicNameLikeOrTopicSrcLikeOrTopicTypeLikeAndMarkedDelIs(searchKey,searchKey,searchKey,searchKey,searchKey,flag);
    }


    public Topic passTopic(String tpid, Boolean flag1) {
        Topic tp=tpr.findOne(tpid);
        tp.setMarkedDel(flag1);
        return tpr.save(tp);
    }

    public Topic selectTopic(String tpid, Boolean flag1) {
        Topic tpc=tpr.findByIdAndMarkedDel(tpid,flag1);
        return tpc;
    }

    public Topic applyTopic(String topicId, String stuId) {
        User user=usr.findOne(stuId);
        user.setTopicId(topicId);
        usr.save(user);
        String realname=user.getRealname();
        String username=user.getUsername();
        DBObject detail=user.getDetail();
        String email=detail.get("email").toString();
        String phone=detail.get("phone").toString();
        BasicDBObject stu=new BasicDBObject();
        stu.put("realname",realname);
        stu.put("username",username);
        stu.put("email",email);
        stu.put("phone",phone);
        Topic tpc=tpr.findOne(topicId);
        List<DBObject> list=new ArrayList<DBObject>();
        if(tpc.getStudentList()!=null){
            list=tpc.getStudentList();
        }
        list.add(stu);
        tpc.setStudentList(list);
        tpc.setChosePerson(tpc.getChosePerson()+1);
        return tpr.save(tpc);
    }

    public Topic saveAndUpdate(String tid, String teacherName, String tel, String topicName, String topicSrc, String topicType, String requirement, String introduction, String limitPerson, Date finalTime, String tpid) {
        Topic tpc=new Topic();
        if (tpid!=null)
            tpc=tpr.findOne(tpid);
        tpc.setTeacherId(tid);
        tpc.setTeacherName(teacherName);
        tpc.setTeacherTel(tel);
        tpc.setTopicName(topicName);
        tpc.setTopicSrc(topicSrc);
        tpc.setTopicType(topicType);
        tpc.setRequirement(requirement);
        tpc.setIntroduction(introduction);
        tpc.setLimitPerson(Integer.parseInt(limitPerson));
        tpc.setFinalTime(finalTime);
        return tpr.save(tpc);
    }

    public void deleteByTid(String tid) {
        tpr.deleteByTeacherId(tid);
    }

    public Topic finishTopic(String topicId, List<String> stuList,List<String> deList) {
        if (deList!=null){
            for (String i:deList){
                User user=usr.findByUsername(i);
                user.setTopicId(null);
                usr.save(user);
            }
        }
        Topic tpc=tpr.findOne(topicId);
        int limitPerson=tpc.getLimitPerson();
        if (stuList==null)
            throw new RuntimeException("no student");
        if (limitPerson<stuList.size())
            throw new RuntimeException("overflow");
        List<DBObject> stuList0=tpc.getStudentList();
        if (stuList0==null){
            for (String i:stuList){
                User user=usr.findByUsername(i);
                user.setTopicId(topicId);
                user.setSelectTopicState("selected");
                usr.save(user);
                String realname=user.getRealname();
                String username=user.getUsername();
                DBObject detail=user.getDetail();
                String email=detail.get("email").toString();
                String phone=detail.get("phone").toString();
                BasicDBObject stu=new BasicDBObject();
                stu.put("realname",realname);
                stu.put("username",username);
                stu.put("email",email);
                stu.put("phone",phone);
                stuList0.add(stu);
            }
            tpc.setState("finished");
            tpc.setStudentList(stuList0);
            tpc.setChosePerson(stuList.size());
            return tpr.save(tpc);
        }
        else {
            List<DBObject> stuList1=new ArrayList<DBObject>();
//            List<String> stuname0=new ArrayList<String>();
//            for (DBObject s:stuList0)
//                stuname0.add(s.get("username").toString());
            for (int i=0;i<stuList.size();i++){
                User user=usr.findByUsername(stuList.get(i));
                user.setTopicId(topicId);
                user.setSelectTopicState("selected");
                usr.save(user);
                String realname=user.getRealname();
                String username=user.getUsername();
                DBObject detail=user.getDetail();
                String email=detail.get("email").toString();
                String phone=detail.get("phone").toString();
                BasicDBObject stu=new BasicDBObject();
                stu.put("realname",realname);
                stu.put("username",username);
                stu.put("email",email);
                stu.put("phone",phone);
                stuList1.add(stu);
            }
            tpc.setState("finished");
            tpc.setStudentList(stuList1);
            tpc.setChosePerson(stuList.size());
            return tpr.save(tpc);
        }
    }

    public Topic cancelChooseTopic(String topicId, String username) {
        User user=usr.findByUsername(username);
        String tpcid=user.getTopicId();
        if (tpcid.equals(topicId)==false)
            throw new RuntimeException("topicId not match sure you select the true one");
        user.setTopicId(null);
        usr.save(user);
        Topic tpc=tpr.findOne(topicId);
        List<DBObject> stulist=tpc.getStudentList();
        if (stulist.size()==1){
            tpc.setChosePerson(0);
            tpc.setStudentList(new ArrayList<DBObject>());
            return tpr.save(tpc);
        }
        for (Iterator<DBObject> iter=stulist.iterator();iter.hasNext();){
            DBObject stu = iter.next();
            if (stu.get("username").equals(username))
                iter.remove();
        }
        tpc.setChosePerson(tpc.getChosePerson()-1);
        tpc.setStudentList(stulist);
        return tpr.save(tpc);
    }


    public Topic chooseNewTopic(String topicId, String username) {
        User user=usr.findByUsername(username);
        String oldtpid=user.getTopicId();
        if (oldtpid==null)
            return applyTopic(topicId,user.getId());
        Topic tpc=tpr.findOne(oldtpid);
        List<DBObject> stulist=tpc.getStudentList();
        if (stulist.size()==1){
            tpc.setChosePerson(0);
            tpc.setStudentList(new ArrayList<DBObject>());
            tpr.save(tpc);
        }else {
            for (Iterator<DBObject> iter = stulist.iterator(); iter.hasNext(); ) {
                DBObject stu = iter.next();
                if (stu.get("username").equals(username))
                    iter.remove();
            }
            tpc.setChosePerson(tpc.getChosePerson()-1);
            tpc.setStudentList(stulist);
            tpr.save(tpc);
        }
        return applyTopic(topicId,user.getId());
    }
}
